#ifndef V_THREAD_MESSAGE_H
#define V_THREAD_MESSAGE_H

#include <chrono>
#include <functional>

namespace VUtils {
    class VThreadMessage {
    public:
        int m_what;
        int m_arg1;
        int m_arg2;
        typedef std::function<void()> Function;
        Function task;

        std::chrono::system_clock::time_point when;

    public:
        VThreadMessage() : VThreadMessage(0, 0, 0, 0) {}

        VThreadMessage(int what) : VThreadMessage(what, 0, 0, 0) {}

        VThreadMessage(int what, int arg1) : VThreadMessage(what, arg1, 0, 0) {}

        VThreadMessage(int what, int arg1, int arg2) : VThreadMessage(what, arg1, arg2, 0) {}

        VThreadMessage(int what, int arg1, int arg2, long uptimeMillis) : m_what(what), m_arg1(arg1),
                                                                                          m_arg2(arg2) {
            when = std::chrono::system_clock::now() + std::chrono::milliseconds(uptimeMillis);
            task = nullptr;
        }

        void setWhen(long uptimeMillis) {
            when = std::chrono::system_clock::now() + std::chrono::milliseconds(uptimeMillis);
        }

        void setFunction(Function f) {
            this->task = f;
        }

        ~VThreadMessage() {

        }

        VThreadMessage &operator=(const VThreadMessage &msg) {
            this->m_arg1 = msg.m_arg1;
            this->m_arg2 = msg.m_arg2;
            this->m_what = msg.m_what;
            this->when = msg.when;
            this->task = msg.task;

            return *this;
        }


        bool operator>(const VThreadMessage &msg) const {
            return (this->when > msg.when);
        }

        bool operator<(const VThreadMessage &msg) const {
            return (this->when < msg.when);
        }

        bool operator==(const VThreadMessage &msg) const {
            return (this->m_what == msg.m_what) && (this->task != nullptr) && (msg.task != nullptr);
        }

        bool operator==(int what) const {
            return (this->m_what == what);
        }
    };
}
#endif
